package org.jeecg.modules.networking.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.jeecg.common.util.RestUtil;
import org.jeecg.modules.networking.util.SM2Utils;
import org.jeecg.modules.networking.util.SM3Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Date;
import java.util.TimeZone;

public class Test {
    //企业编码
    private static final String ENTERPRISE_CODE = "a0cd42ed728a47ae8c";
    //密钥
    private static final String SECRET_KEY = "YmNJKmYrF8dwWQVQaKOqXGQri7cEFG3peztdB4BeKBaN8j38vblIGp94wnSOw5mJ";
    //企业门禁系统联网对接用户名
    private static final String USERNAME = "15245857333832392715";
    //企业门禁系统联网对接密码
    private static final String ALLOC_PASSWORD = "Go4QZ9Qa6W5Ope8RSIM70Ak9sKhjuR";
    //台账对接测试地址
    private static final String BASE_URL = "https://t.jdc.taep.org.cn:17701";
    //Token
    private static final String ACCESS_TOKEN = "6f9458acb4d8450b88e160eab3658236";
    //企业唯一编码标识
    private static final String COMPANY_CODE = "a0cd42ed728a47ae8c";
    //公钥
    private static final String PUBLIC_KEY = "0367d52780895aeb13860f0b1a89236c1b7747dc66c431dda06debd1835c5817cc";
    private static final Logger log = LoggerFactory.getLogger(Test.class);

    public static void main(String[] args) throws Exception {
        JSONObject getAccessToken = getAccessToken();
        log.info("getAccessToken: {}", getAccessToken);
    }

    //8.1 获取授权码及服务器时间接口 - 成功
    public static JSONObject getAccessToken(){
        String url = BASE_URL + "/api/v1/token/getAccessToken";
        JSONObject request = new JSONObject();
        request.put("username", USERNAME);
        request.put("encrypt_method", 2);
        LocalDateTime localDateTime = LocalDateTime.now().plusSeconds(30);
        long timestamp = localDateTime.toEpochSecond(ZoneOffset.UTC);
        request.put("requestTimestamp", timestamp);
        // 构建待加密字符串
        String toEncrypt = USERNAME + timestamp + ALLOC_PASSWORD;
        // 执行SM3加密
        String encryptedPassword = SM3Util.encryptSM3(toEncrypt);
        request.put("password", encryptedPassword);
        return RestUtil.post(url, request);
    }

    //8.2 信息同步接口 - 成功
    public static JSONObject syncInfo(){
        String url = BASE_URL + "/api/v1/sync/syncInfo";
        JSONObject request = new JSONObject();
        request.put("company_code", COMPANY_CODE);
        request.put("access_token", ACCESS_TOKEN);
        return RestUtil.post(url, request);
    }

    //8.3 上报车辆备案信息接口 - 成功
    public static JSONObject putRegisterVehicleInfo() throws InvalidCipherTextException, IOException {
        String url = BASE_URL + "/api/v1/vehicleInfo/putRegisterVehicleInfo";
        JSONObject value = new JSONObject();
        value.put("plateNo", "津C33573");
        value.put("plateColor", "1");
        value.put("vehicleType", "H12");
        value.put("vin", "LGAX3AG49LT025516");
        value.put("engineNo", "L3205052");
        value.put("registerDate", "20201127");
        value.put("vehicleBrand", "东风牌DFH5180XYKEX6");
        value.put("vehicleModel", "东风牌DFH5180XYKEX6");
        value.put("fuelType", "B");
        value.put("engineType", "123");
        value.put("engineManufacturer", "123");
        value.put("emissionStandard", "6");
        value.put("connectedStatus", "1");
        value.put("useCharacter", "F");
        value.put("owner", "中外运-日新国际货运有限公司天津分公司");
        JSONObject request = new JSONObject();
        request.put("company_code", COMPANY_CODE);
        request.put("access_token", ACCESS_TOKEN);
        request.put("encrypt_method", "2");
        request.put("value", encrypt(value));
        String envLicense = "https://taiwei-menjin.oss-cn-beijing.aliyuncs.com/2024-08-06/1722934634930_1722934652179.jpg";
        String drivingLicense = "https://taiwei-menjin.oss-cn-beijing.aliyuncs.com/2024-08-06/1722934568213_1722934587432.jpg";
        String envLicenseImg = compressPicForScale(envLicense, 2048);
        String drivingLicenseImg = compressPicForScale(drivingLicense, 2048);
        request.put("envLicenseImg", getSwitch(envLicense, envLicenseImg));
        request.put("drivingLicenseImg", getSwitch(drivingLicense, drivingLicenseImg));
        return RestUtil.post(url, request);
    }

    //8.4 上报车辆通行记录信息接口 - 成功
    public static JSONObject putVehiclePassRecords() throws InvalidCipherTextException, IOException {
        String url = BASE_URL + "/api/v1/vehiclePassRecords/putVehiclePassRecords";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));//设置北京时间
        JSONObject value = new JSONObject();
        value.put("serialNo", COMPANY_CODE + "A01" + "1" + simpleDateFormat.format(new Date()));
        value.put("entranceNo", "A");
        value.put("gateNo", "A01");
        value.put("passStatus", "1");
        value.put("passTime", "2024-08-09 13:44:42");
        value.put("plateNo", "津C33573");
        value.put("plateColor", "1");
        value.put("vehicleType", "H12");
        value.put("vin", "LGAX3AG49LT025516");
        value.put("engineNo", "L3205052");
        value.put("registerDate", "20201127");
        value.put("vehicleBrand", "东风牌DFH5180XYKEX6");
        value.put("vehicleModel", "东风牌DFH5180XYKEX6");
        value.put("fuelType", "B");
        value.put("engineType", "123");
        value.put("engineManufacturer", "123");
        value.put("emissionStandard", "6");
        value.put("connectedStatus", "1");

        value.put("handMove", "0");
        value.put("useCharacter", "F");
        value.put("transportGoods", "塑料颗粒");
        value.put("transportGoodType", "1");
        value.put("transportVolume", "7.00");
        value.put("transportGoodsUnit", "1");
        value.put("dataComment", "");

        JSONObject request = new JSONObject();
        request.put("company_code", COMPANY_CODE);
        request.put("access_token", ACCESS_TOKEN);
        request.put("encrypt_method", "2");
        request.put("value", encrypt(value));
        String envLicense = "https://taiwei-menjin.oss-cn-beijing.aliyuncs.com/2024-08-06/1722934634930_1722934652179.jpg";
        String drivingLicense = "https://taiwei-menjin.oss-cn-beijing.aliyuncs.com/2024-08-06/1722934568213_1722934587432.jpg";
        String envLicenseImg = compressPicForScale(envLicense, 2048);
        String drivingLicenseImg = compressPicForScale(drivingLicense, 2048);
        request.put("vehicleHeadImg", getSwitch(envLicense, envLicenseImg));
        request.put("vehicleBodyImg", getSwitch(drivingLicense, drivingLicenseImg));
        return RestUtil.post(url, request);
    }

    //8.5 上报厂内运输车辆信息接口 - 成功
    public static JSONObject putVehicleInfo() throws InvalidCipherTextException, IOException {
        String url = BASE_URL + "/api/v1/innerVehicle/putVehicleInfo";
        JSONObject value = new JSONObject();
        value.put("envRegisterCode", "A");
        value.put("provRegisterCode", "A01");
        value.put("vin", "1");
        value.put("manufactureDate", "20240809");
        value.put("plateNo", "津C33573");
        value.put("registerDate", "20240809");
        value.put("vehicleBrand", "东风牌DFH5180XYKEX6");
        value.put("vehicleModel", "东风牌DFH5180XYKEX6");
        value.put("fuelType", "B");
        value.put("emissionStandard", "6");
        value.put("connectedStatus", "1");
        value.put("owner", "中外运-日新国际货运有限公司天津分公司");
        JSONObject request = new JSONObject();
        request.put("company_code", COMPANY_CODE);
        request.put("access_token", ACCESS_TOKEN);
        request.put("encrypt_method", "2");
        request.put("value", encrypt(value));
        String envLicense = "https://taiwei-menjin.oss-cn-beijing.aliyuncs.com/2024-08-06/1722934634930_1722934652179.jpg";
        String drivingLicense = "https://taiwei-menjin.oss-cn-beijing.aliyuncs.com/2024-08-06/1722934568213_1722934587432.jpg";
        String envLicenseImg = compressPicForScale(envLicense, 2048);
        String drivingLicenseImg = compressPicForScale(drivingLicense, 2048);
        request.put("envLicenseImg", getSwitch(envLicense, envLicenseImg));
        request.put("drivingLicenseImg", getSwitch(drivingLicense, drivingLicenseImg));
        return RestUtil.post(url, request);
    }

    //8.6 上报非道路移动机械信息接口 - 成功
    public static JSONObject putRegisterNRMM() throws InvalidCipherTextException, IOException {
        String url = BASE_URL + "/api/v1/nrmm/putRegisterNRMM";
        JSONObject value = new JSONObject();
        value.put("envRegisterCode", "A");
        value.put("provRegisterCode", "A01");
        value.put("manufactureDate", "20160809");
        value.put("plateNo", "津C33573");
        value.put("fuelType", "B");
        value.put("emissionStandard", "6");

        value.put("mechanicalType", "4");
        value.put("pin", "DFH5180XYKEX6");
        value.put("mechanicalModel", "东风牌DFH5180XYKEX6");
        value.put("engineModel", "1");
        value.put("engineManufacture", "中外运-日新国际货运有限公司天津分公司");
        value.put("engineNo", "111");
        value.put("onwer", "123");
        JSONObject request = new JSONObject();
        request.put("company_code", COMPANY_CODE);
        request.put("access_token", ACCESS_TOKEN);
        request.put("encrypt_method", "2");
        request.put("value", encrypt(value));
        String envLicense = "https://taiwei-menjin.oss-cn-beijing.aliyuncs.com/2024-08-06/1722934634930_1722934652179.jpg";
        String drivingLicense = "https://taiwei-menjin.oss-cn-beijing.aliyuncs.com/2024-08-06/1722934568213_1722934587432.jpg";
        String envLicenseImg = compressPicForScale(envLicense, 2048);
        String drivingLicenseImg = compressPicForScale(drivingLicense, 2048);
        request.put("nameplateImg", getSwitch(envLicense, envLicenseImg));
        request.put("engineNameplateImg", getSwitch(drivingLicense, drivingLicenseImg));
        request.put("mechineEnvLabelImg", "");
        return RestUtil.post(url, request);
    }

    //8.7 上报排放超标信息核实结果接口 - 成功
    public static JSONObject putVehicleCheckResult() throws InvalidCipherTextException, IOException {
        String url = BASE_URL + "/api/v1/vehicleBlacklist/checkVehicle/putVehicleCheckResult";
        JSONObject value = new JSONObject();
        value.put("plateNo", "津C33573");
        value.put("plateColor", "1");
        value.put("vin", "津C33573");
        value.put("fuelType", "B");
        value.put("emissionStandard", "6");
        value.put("emissionCheckRes", "1");
        value.put("emissionCheckDate", "20241009");
        value.put("emissionCheckComment", "1");
        JSONObject request = new JSONObject();
        request.put("company_code", COMPANY_CODE);
        request.put("access_token", ACCESS_TOKEN);
        request.put("encrypt_method", "2");
        request.put("value", encrypt(value));
        return RestUtil.post(url, request);
    }

    //8.8 上报每日运输车辆进厂台次总数接口
    public static JSONObject putVehiclePassRecordsNum() throws InvalidCipherTextException, IOException {
        String url = BASE_URL + "/api/v1/vehiclePassRecords/putVehiclePassRecordsNum";
        JSONObject value = new JSONObject();
        value.put("day", "20241008");
        value.put("entranceNo", "A");
        value.put("gateNo", "A01");
        value.put("recordsNumber", "0");
        JSONObject request = new JSONObject();
        request.put("company_code", COMPANY_CODE);
        request.put("access_token", ACCESS_TOKEN);
        request.put("encrypt_method", "2");
        request.put("value", encrypt(value));
        return RestUtil.post(url, request);
    }

    //8.9违规通行车辆名单查询接口 - 成功
    public static JSONObject breakPassRules(){
        String url = BASE_URL + "/api/v1/vehicleBlacklist/breakPassRules/getVehicleInfos";
        JSONObject request = new JSONObject();
        request.put("company_code", COMPANY_CODE);
        request.put("access_token", ACCESS_TOKEN);
        return RestUtil.post(url, request);
    }

    //8.10 黑名单车辆查询接口 - 成功
    public static JSONObject breakEnvRules(){
        String url = BASE_URL + "/api/v1/vehicleBlacklist/breakEnvRules/getVehicleInfos";
        JSONObject request = new JSONObject();
        request.put("company_code", COMPANY_CODE);
        request.put("access_token", ACCESS_TOKEN);
        return RestUtil.post(url, request);
    }

    //8.11 移动源管控措施查询接口 - 成功
    public static JSONObject getControlStrategy(){
        String url = BASE_URL + "/api/v1/VehicleControlStrategy/getControlStrategy";
        JSONObject request = new JSONObject();
        request.put("company_code", COMPANY_CODE);
        request.put("access_token", ACCESS_TOKEN);
        return RestUtil.post(url, request);
    }

    public static String encrypt(JSONObject jsonObject) throws InvalidCipherTextException {

        String jsonString = jsonObject.toJSONString();
        return SM2Utils.encrypt(PUBLIC_KEY, jsonString);
    }

    /**
     * 根据指定大小压缩图片
     *
     * @param imagePath  源图片地址（网络地址）
     * @param desFileSize 指定图片大小，单位kb
     * @return 压缩质量后的图片字节数组
     */
    public static String compressPicForScale(String imagePath, long desFileSize) throws IOException {
        byte[] data = getBytesFromHost(imagePath);

        if (data.length < desFileSize * 1024) {
            return Base64.encodeBase64String(data);
        }

        long srcSize = data.length;
        double accuracy = getAccuracy(srcSize / 1024);

        try {
            while (data.length > desFileSize * 1024) {
                try (ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
                     ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length)) {
                    Thumbnails.of(inputStream)
                            .scale(accuracy)
                            .outputQuality(accuracy)
                            .toOutputStream(outputStream);
                    data = outputStream.toByteArray();
                }
            }
            log.info("图片原大小={}kb | 压缩后大小={}kb", srcSize / 1024, data.length / 1024);
        } catch (Exception e) {
            log.error(String.format("【图片压缩】msg=图片压缩失败! imagePath=%s, desFileSize=%d", imagePath, desFileSize));
            throw e; // 重新抛出异常以便调用者处理
        }

        return Base64.encodeBase64String(data);
    }

    public static byte[] getBytesFromHost(String imagePath) throws IOException {
        try (InputStream in = new URL(imagePath).openStream();
             ByteArrayOutputStream data = new ByteArrayOutputStream()) {
            final byte[] buffer = new byte[4096]; // 增加缓冲区大小
            int bytesRead;
            while ((bytesRead = in.read(buffer)) != -1) {
                data.write(buffer, 0, bytesRead);
            }
            return data.toByteArray();
        }
    }

    /**
     * 自动调节精度(经验数值)
     *
     * @param size 源图片大小
     * @return 图片压缩质量比
     */
    private static double getAccuracy(long size) {
        double accuracy;
        if (size < 900) {
            accuracy = 0.85;
        } else if (size < 2047) {
            accuracy = 0.6;
        } else if (size < 3275) {
            accuracy = 0.44;
        } else {
            accuracy = 0.4;
        }
        return accuracy;
    }

    /** *filename文件名  base64 */
    public static String getSwitch(String filename,String base64) {
        String str = filename.substring(filename.lastIndexOf(".") + 1);
        System.out.println(str);
        //png
        String pngPrefix = "data:image/png;base64,";
        //jpg
        String jpegPrefix = "data:image/jpeg;base64,";
        //docx
        String docxPrefix = "data:application/vnd.openxmlformats-officedocument.wordprocessingml.document ;base64,";
        //doc
        String docPrefix = "data:application/msword;base64,";
        //pdf
        String pdfPrefix = "data:application/pdf;base64,";
        String filebase64 = null;
        if (StringUtils.isNotBlank(str)) {
            switch (str) {
                case "png":
                    filebase64 = pngPrefix.concat(base64);
                    break;
                case "jpg":
                    filebase64 = jpegPrefix.concat(base64);
                    break;
                case "docx":
                    filebase64 = docxPrefix.concat(base64);
                    break;
                case "doc":
                    filebase64 = docPrefix.concat(base64);
                    break;
                case "pdf":
                    filebase64 = pdfPrefix.concat(base64);
                    break;
                default:
                    break;
            }
        }
        return  filebase64;
    }

}
